package com.zjpavt.client.extenddevice.loop.loopcontroller;

import java.io.IOException;
import java.text.DecimalFormat;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.zjpavt.client.extenddevice.AbstractExtendDevice;
import com.zjpavt.client.extenddevice.IExtendDevice;
import com.zjpavt.client.extenddevice.IVoltageAndCurrentDetection;
import com.zjpavt.client.extenddevice.helpbean.OwnerDevice;
import com.zjpavt.client.nativemethod.JnIMethod;
import com.zjpavt.client.util.LoggerUtil;
import com.zjpavt.client.util.PropertiesUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 电压电流检测模块（回路控制器内嵌的电压电流检测功能）
 * 修改相位，查询电压电流数据（U指令，电压电流显示页面） 外部调用
 * 实时获取检测模块的数据（通过485接口）
 * @author zyc
 */
@Slf4j
public class VoltageAndCurrentDetection extends AbstractExtendDevice implements OwnerDevice, IVoltageAndCurrentDetection {


    public VoltageAndCurrentDetection(int loopNum, int extNum, IExtendDevice device) {
        super(extNum, device.getDeviceType());
        this.extendNum = extNum;
        this.loopNum = loopNum;
        this.owner = device;
        currentEveryLoop = new ArrayList<>(loopNum);
        phaseEveryLoop = new ArrayList<>(loopNum);
        try {
            for (int i = 0; i < loopNum; i++) {
                currentEveryLoop.add(0D);
                phaseEveryLoop.add('A');
            }
            String voltagePhase = PropertiesUtil.getPropertiesDefault(CURRENT_PHASE_KEY + extNum);
            initPhase(voltagePhase);
        } catch (IOException e) {
            log.error(LoggerUtil.convertException2String(e));
        }
    }

    public void setBeginIndex(int beginIndex) {
        this.beginIndex = beginIndex;
    }

    public void savePhaseString() {
        StringBuilder phaseStringBuilder = new StringBuilder();
        for (int i = 0; i < loopNum; i++) {
            phaseStringBuilder.append(getPhase(i));
        }
        try {
            PropertiesUtil.setPropertyOrReplaceDefault(CURRENT_PHASE_KEY+ extendNum, phaseStringBuilder.toString());
        } catch (IOException e) {
            log.error("set properties fail");
        }
    }

    /**
     * 初始化电压电流相位
     */
    private void initPhase(String phaseString) {
//      如果缓存的电压电流相位大于当前的回路数量 则沿用当前设置
        if ( phaseString != null && phaseString.length() >= loopNum) {
            for (int i = 0; i < loopNum; i++) {
                this.phaseEveryLoop.set(i, phaseString.charAt(i));
            }
        } else {
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < loopNum; i++) {
                char phase = (char) ('A' + (i % 3));
//            将每一个回路的相位初始化为ABCABC
                phaseEveryLoop.set(i, phase);
                stringBuilder.append(phase);
            }
            try {
                PropertiesUtil.setPropertyOrReplaceDefault(CURRENT_PHASE_KEY+ extendNum, stringBuilder.toString());
            } catch (IOException e) {
                log.error("set properties fail");
            }
        }
    }
    /**
     *
     * @param current
     * @param loopIndex   在当前电压电流模块中的序列号，从1开始
     */
    public void setCurrent(double current,int loopIndex) {
        currentEveryLoop.set(loopIndex - 1, current);
    }

    /**
     * 每次修改相位后保存修改到文件
     * @param phase
     * @param loopIndex
     */
    public void setPhase(char phase, int loopIndex) {
        phaseEveryLoop.set(loopIndex - 1, phase);
        savePhaseString();
    }

    /**
     * 每次修改相位后保存修改到文件
     * @param phaseString 所有相位的字符串
     */
    public void setPhase(String phaseString) {
        for (int i = 0; i < phaseString.length(); i++) {
            phaseEveryLoop.set(i, phaseString.charAt(i));
        }
        try {
            PropertiesUtil.setPropertyOrReplaceDefault(CURRENT_PHASE_KEY+ extendNum, phaseString);
        } catch (IOException e) {
            log.error("set properties fail");
        }
    }

    /**
     *
     * @param loopIndex 从1开始
     * @return
     */
    private double getCurrent(int loopIndex) {
        return currentEveryLoop.get(loopIndex - 1);
    }

    /**
     * 获取某个回路的相位
     * @param loopIndex 从1开始
     * @return
     */
    private char getPhase(int loopIndex) {
        return phaseEveryLoop.get(loopIndex - 1);
    }

    private double getVoltage(char voltagePhase) {
        switch (voltagePhase) {
        case 'a':
        case 'A':
            return voltageAPhase;
        case 'b':
        case 'B':
            return voltageBPhase;
        case 'c':
        case 'C':
            return voltageCPhase;
        default:
            log.error("can't find phase" + voltagePhase);
            return 0;
        }
    }
    
    private static final Pattern VOLTAGE_CURRENT_PATTERN =
            Pattern.compile("<CIRCUIT_CURRENT_DATA_CH[0-9]{1,2}_\\[A_(?<A>\\d{1,3}\\.\\d)]\\[B_(?<B>\\d{1,3}\\.\\d)]\\[C_(?<C>\\d{1,3}\\.\\d)]" +
                    "(?:\\[[0-9]{1,3}/[0-9.]{1,5}/[01]])*>");
    /** [序列号/电流值/回路通断]     [001/11.81/1]     */
    private static final Pattern CURRENT_PATTERN = Pattern.compile("\\[(?<index>[0-9]{1,3})/(?<current>[0-9\\.]{1,5})/(?<open>[01])]");

    /**
     * 根据检测模块更新电流电压数据
     */
    public void updateInformation() {
        String message = JnIMethod.sendMessage2ExtendDeviceByRs485DefaultBanudRate( extendNum, "<AT_CHECK0_CIRCUIT_CURRENT_DATA>", 200);
        if (message == null) {
            getOwnerDevice().getUnderDeviceInteractionBean().interactionFail();
            return;
        } else {
            getOwnerDevice().getUnderDeviceInteractionBean().interactionSuccess();
        }
        Matcher matcher = VOLTAGE_CURRENT_PATTERN.matcher(message);
        if (matcher.matches()) {
            try {
                voltageAPhase = Double.parseDouble(matcher.group("A"));
                voltageBPhase = Double.parseDouble(matcher.group("B"));
                voltageCPhase = Double.parseDouble(matcher.group("C"));
            } catch (NumberFormatException e) {
                log.error(LoggerUtil.convertException2String(e));
            }
        }
        Matcher currentMatcher = CURRENT_PATTERN.matcher(message);
        while (currentMatcher.find()) {
            //index从1开始
            try {
                int index = Integer.parseInt(currentMatcher.group("index"));
                double current = Double.parseDouble(currentMatcher.group("current"));
                setCurrent(current, index);
            } catch (Exception e) {
                log.error(LoggerUtil.convertException2String(e));
            }
        }
    }
    /**
     *  返回给U指令使用   [001_A/220/20.0]...
     * @return		返回格式化后的字符串
     */
    @Override
    public List<String> getFormattedAllCurrentAndVoltage() {
        updateInformation();
        
        StringBuilder builder=new StringBuilder();
        List<String> formatList = new ArrayList<>(loopNum);
        for (int i = 1; i <= loopNum; ++i) {
            getFormattedCurrentAndVoltageInternal(i, builder);
            formatList.add(builder.toString());
            builder.setLength(0);
        }
        return formatList;
    }

    /**
     *  返回给U指令使用   [001_A/220/20.0]
     * @param index  当前回路控制器中的序号 从1开始
     * @return		返回格式化后的字符串
     */
    @Override
    public String getFormattedCurrentAndVoltage(int index) {
        StringBuilder builder=new StringBuilder();
        getFormattedCurrentAndVoltageInternal(index, builder);
        
        return builder.toString();
    }
/**
 *  [0-001_A/220/20.0]
 * @param index
 * @param builder
 * @return
 */
    protected final StringBuilder getFormattedCurrentAndVoltageInternal(int index, StringBuilder builder) {

        char loopPhase = getPhase(index);
        builder.append('[');
        //builder.append(extendNum).append('-');
        builder.append(INDEX_FORMAT.format(index + beginIndex)).append('_').append(loopPhase).append('/');
        builder.append(VOLTAGE_FORMAT.format(getVoltage(loopPhase))).append('/');
        builder.append(CURRENT_FORMAT.format(getCurrent(index))).append(']');
        return builder;
    }

    @Override
    public String getAllPhase() {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 1; i <= loopNum; i++) {
            stringBuilder.append(getPhase(i));
        }
        return stringBuilder.toString();
    }

    /**
     * 设置所有相位
     * @param phaseString
     */
    @Override
    public void setAllPhase(String phaseString) {
        if (getAllPhase().equals(phaseString) || phaseString.length() != loopNum) {
            return;
        } else {
            setPhase(phaseString);
        }
    }


    @Override
    public int getLoopNum() {
        return loopNum;
    }

    @Override
    public IExtendDevice getOwnerDevice() {
        return owner;
    }
    
    /**
     * 返回给U指令使用   [1_A/220/20.0] 的格式化形式
     */
    public static final DecimalFormat VOLTAGE_FORMAT = new DecimalFormat("000");
    public static final DecimalFormat CURRENT_FORMAT = new DecimalFormat("#0.0");
    public static final DecimalFormat INDEX_FORMAT = new DecimalFormat("000");

    public static final String CURRENT_PHASE_KEY = "currents_phase";
    /**
     * 持有对象
     */
    protected IExtendDevice owner;

    /**
     * 电压电流
     */
    protected int loopNum;
    /**
     * A,B,C 三相电压
     */
    protected double voltageAPhase;
    protected double voltageBPhase;
    protected double voltageCPhase;
    /**
     * 每一个回路的电流
     */
    protected AbstractList<Double> currentEveryLoop = null;
    protected AbstractList<Character> phaseEveryLoop = null;
    /**
     * 当前电压电流检测模块在所有电压电流检测模块中开始的序号 默认为0,
     * 如果前面已经有12个检测模块则设置为12
     */
    protected int beginIndex = 0;
}
